<template>
  <div class="color-picker">
    <div class="color-select">
      <span>{{title}}</span>
      <span style="font-size: 12px; color: rgba(47, 46, 63, 0.65)"
        >渐变类型</span
      >
      <div class="color-column">
        <span
          class="color-title"
          v-for="(item, index) in gradientTypeList"
          :key="index"
          :class="{ 'color-type': colorGroup.type === item.key }"
          @click="changeGradienKey(item)"
        >
          {{ item.name }}
        </span>
      </div>
      <div class="color-column-group">
        <span style="font-size: 12px; color: rgba(47, 46, 63, 0.65)">颜色</span>
        <div class="color-group-ul">
          <div
            class="color-li"
            v-for="(color, index) in colorGroup.colors"
            :key="index"
            @click="open($event, color, index)"
          >
            <div class="color-item" :style="{ background: color }">
              <div class="color-item-setting">
                <span>{{ color }}</span>
                <div class="btn">
                  <span @click.stop="add(index)">新增</span>
                  <span @click.stop="dele(index)">删除</span>
                </div>
              </div>
            </div>
            <div class="line"></div>
          </div>
        </div>
      </div>
      <!-- <span style="font-size: 12px; color: rgba(47, 46, 63, 0.65)">角度</span>
      <div class="color-column-angle">
        <el-slider
          v-model="colorGroup.angle"
          :min="0"
          :max="360"
          style="width: 100%"
        ></el-slider>
      </div> -->
      <span style="font-size: 12px; color: rgba(47, 46, 63, 0.65)"
        >渐变角度</span
      >
      <div class="color-column-angle">
        <div class="color-column-angle-box">
          <div
            class="angle-box-content"
            :style="{
              backgroundImage: $methods.gradientReturnString('bg', colorGroup),
            }"
          >
            <!-- scale scale-line -->
            <div
              class="scale scale-background"
              v-for="i in 4"
              :key="i"
            ></div>
            <div
              class="pointer"
              v-drage="changeRotate"
              :style="{
                transform: `rotate(${colorGroup.angle}deg)`,
              }"
            />
          </div>
        </div>
        <vxe-input
          v-model="colorGroup.angle"
          placeholder="渐变角度"
          type="number"
          style="width: 125px"
        />
      </div>
    </div>
    <!-- 颜色选择框 -->
    <div
      class="popover-container"
      ref="popover"
      v-if="visible"
      @click="handle($event)"
    >
      <div
        id="dialog"
        class="popover-dialog-color"
        ref="dialog"
        :style="{
          top: `${top}px`,
        }"
      >
        <sketch-picker :value="color" @input="colorValueChange" />
      </div>
    </div>
  </div>
</template>

<script>
import { Sketch } from "vue-color";
export default {
  components: {
    "sketch-picker": Sketch,
  },
  props: {
    value: Object,
    type: String,
    title: {
      type: String,
      required: false,
    },
  },
  directives: {
    drage: {
      bind(el, binding) {
        el.onmousedown = (e) => {
          // 鼠标按下，计算当前元素距离可视区的距离
          let screenTop = el.getBoundingClientRect().top;
          let screenLeft = el.getBoundingClientRect().left;
          let width = el.getBoundingClientRect().width;
          let height = el.getBoundingClientRect().height;
          document.body.style.cursor = "pointer";
          // 获取起始点
          const startX = e.clientX;
          const startY = e.clientY;

          // 旋转点
          const centerX = screenLeft + width / 2;
          const centerY = screenTop + height;

          // 旋转前的角度
          const rotateDegreeBefore =
            Math.atan2(startY - centerY, startX - centerX) / (Math.PI / 180);

          document.onmousemove = function (event) {
            const curX = event.clientX;
            const curY = event.clientY;
            // 旋转后的角度
            const rotateDegreeAfter =
              Math.atan2(curY - centerY, curX - centerX) / (Math.PI / 180);
            binding.value(rotateDegreeAfter - rotateDegreeBefore);
          };

          document.onmouseup = function (e) {
            document.onmousemove = null;
            document.onmouseup = null;
          };
        };
      },
    },
  },
  data() {
    return {
      gradientTypeList: [
        {
          name: "线性渐变",
          key: "linear-gradient",
        },
        {
          name: "径向渐变",
          key: "radial-gradient",
        },
      ],
      gradientKey: "linear-gradient",
      angle: 0,
      colorGroup: this.value,
      top: 0,
      visible: false,
      color: "#FFFFFF",
      index: 0,
    };
  },
  computed: {
    backgroundImage() {
      return `linear-gradient(to bottom,red,blue, yellow)`;
    },
  },
  methods: {
    changeRotate(rotate) {
      this.colorGroup.angle = parseInt(rotate);
      this.$emit("change", {
        key: this.type,
        value: this.colorGroup,
      });
    },
    open(e, color, index) {
      this.visible = true;
      this.color = color;
      this.index = index;
      // 设置颜色选择框的位置
      this.$nextTick((_) => {
        const designDom = document.getElementById("dialog");
        const bodyHeight = document.body.offsetHeight;
        const designHeight = designDom.offsetHeight;
        if (bodyHeight - e.clientY < designHeight) {
          this.top = e.clientY - designHeight / 2;
          return;
        }
        this.top = e.clientY;
      });
    },
    add(index) {
      this.colorGroup.colors.splice(index + 1, 0, "#fffff");
      this.$emit("change", {
        key: this.type,
        value: this.colorGroup,
      });
    },
    dele(index) {
      if (this.colorGroup.colors.length > 1) {
        this.colorGroup.colors.splice(index, 1);
      }
      this.$emit("change", {
        key: this.type,
        value: this.colorGroup,
      });
    },
    handle(e) {
      // 点击空白区域关闭
      if (e.target != this.$refs.popover) {
        return;
      }
      this.visible = false;
    },
    colorValueChange(data) {
      this.color = data.hex8;
      if (this.index != null) {
        this.colorGroup.colors[this.index] = data.hex8;
      }
      this.$emit("change", {
        key: this.type,
        value: this.colorGroup,
      });
    },
    changeGradienKey(data) {
      this.colorGroup.type = data.key;
      this.$emit("change", {
        key: this.type,
        value: this.colorGroup,
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.color-column-angle-box {
  width: 64px;
  height: 64px;
  margin: 6px 0;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 50%;
  background: #eeeff1;
  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12), 0 0 6px 0 rgba(0, 0, 0, 0.04);

  .angle-box-content {
    position: relative;
    width: calc(100% - 12px);
    height: calc(100% - 12px);
    margin: 0 auto;
    display: flex;
    justify-content: center;
    align-items: flex-start;
    border-radius: 50%;

    .scale-background {
      background: #cecfd0;
    }

    .scale-line {
      position: absolute;
      width: 1px;
      height: 4px;
      transform: rotate(45deg);
    }

    .scale:nth-child(1) {
      position: absolute;
      top: 0px;
      left: 50%;
      width: 1px;
      height: 4px;
      transform: translateX(-50%);
    }

    .scale:nth-child(2) {
      position: absolute;
      top: 50%;
      right: 0px;
      width: 4px;
      height: 1px;
      transform: translateY(-50%);
    }

    .scale:nth-child(3) {
      position: absolute;
      bottom: 0px;
      right: 50%;
      width: 1px;
      height: 4px;
      transform: translateX(-50%);
    }

    .scale:nth-child(4) {
      position: absolute;
      top: 50%;
      left: 0px;
      width: 4px;
      height: 1px;
      transform: translateY(-50%);
    }

    .pointer {
      position: relative;
      width: 4px;
      background: #b082e99c;
      height: 50%;
      border-radius: 4px;
      transform: rotate(0deg);
      transform-origin: 50% 100%;

      &::after {
        position: absolute;
        display: inline-block;
        content: "";
        width: 6px;
        height: 6px;
        bottom: -3px;
        left: 50%;
        transform: translateX(-50%);
        background: #b182e9;
        border-radius: 50%;
        // border: 1px solid #000;
        // box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12),
        //   0 0 6px 0 rgba(0, 0, 0, 0.04);
      }

      &::before {
        position: absolute;
        display: inline-block;
        content: "";
        width: 8px;
        height: 8px;
        top: -4px;
        left: 50%;
        transform: translate(-50%, -25%);
        background: #b182e9;
        border-radius: 50%;
        box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.238),
          0 0 6px 0 rgba(0, 0, 0, 0.056);
        cursor: pointer;
      }
    }
  }
}
</style>

<style scoped lang="scss">
.popover-container {
  position: absolute;
  top: 0px;
  left: 0px;
  width: 100vw;
  height: 100vh;
}

.popover-dialog-color {
  position: absolute;
  top: 50px;
  right: 244px;
  padding: 6px;
  width: 232px;
  transform: translateY(-50%);
  background: #fff;
  border-radius: 4px;
  box-shadow: rgba(0, 0, 0, 0.1) 0px 3px 10px 0px;
  border: 1px solid var(--border-color);
  z-index: 1024;

  ::v-deep {
    .vc-sketch {
      position: relative;
      width: 220px;
      padding: 0;
      box-sizing: initial;
      background: #fff;
      border-radius: 0px;
      box-shadow: none;
    }

    .vc-sketch-presets {
      display: none !important;
      margin-right: -10px;
      margin-left: -10px;
      padding-left: 10px;
      padding-top: 10px;
      border-top: 1px solid #eee;
    }
  }
}

.color-content {
  width: 100%;

  & select {
    border: 1px solid #eee !important;
  }

  .color-right {
    height: 21px;
    display: flex;
    justify-content: flex-start;
    align-items: center;

    .clear {
      color: #000;
      font-size: 13px;

      &:hover {
        cursor: pointer;
        color: #409eff;
      }
    }
  }

  .color-type-title {
    display: flex;
    justify-content: space-between;
    align-content: center;

    & span {
      font-size: 14px;
    }

    .create-color {
      padding: 1px;
      width: 20px;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 14px;
      border-radius: 2px;
      margin-right: 8px;

      .svg-icon {
        width: 14px;
      }

      &:hover {
        color: #409eff;
        background: rgba(0, 0, 0, 0.026);
      }
    }
  }

  .colors-presets {
    width: 220px;
    height: 460px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    flex-wrap: wrap;
    box-sizing: border-box;

    &::-webkit-scrollbar {
      display: none;
    }

    .colors-list {
      width: 100%;
      margin-top: 6px;
    }
    .color-label {
      width: 100%;
      font-size: 14px;
      color: #333;
    }
    .color-group {
      width: 100%;
      height: 16px;
      border-radius: 2px;
      overflow: hidden;
      background: #eee;
      display: flex;
      align-items: center;
      justify-content: space-between;
      cursor: pointer;

      .colors-item {
        flex: 1;
        height: 100%;
      }
    }
  }
}

.color-picker {
  width: 100%;
  box-sizing: border-box;
  border-radius: 2px;
  transition: all 0.28s;

  .color-select {
    width: 100%;
    height: 100%;
    padding: 0px 10px;
    align-items: center;
    justify-content: center;

    .color-column {
      width: 100%;
      display: flex;
      justify-content: flex-start;
      align-items: center;
      margin-top: 10px;
    }

    .color-column-group {
      width: 100%;
      padding: 12px 0;
    }

    .color-column-angle {
      width: 100%;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .color-title {
      flex: 1;
      font-size: 12px;
      color: #000;
      cursor: pointer;
      text-align: center;
      transition: all 0.28s ease;
    }

    .color-type {
      background: #409eff;
      color: #fff;
      border-radius: 2px;
      box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12), 0 0 6px 0 rgba(0, 0, 0, 0.04);
    }

    .linear-gradient {
      display: inline-block;
      width: 20px;
      height: 20px;
      border-radius: 50%;
      color: #fff;
      padding: 6px;
      background-image: linear-gradient(90deg, #f8f7f733, #409eff);
      cursor: pointer;
    }

    .radial-gradient {
      display: inline-block;
      width: 20px;
      height: 20px;
      border-radius: 50%;
      color: #fff;
      padding: 6px;
      background-image: radial-gradient(circle, #f8f7f733 10%, #409eff 80%);
      cursor: pointer;
    }

    .color-group {
      width: 100%;
      height: 16px;
      border-radius: 2px;
      overflow: hidden;
    }
  }

  .color-default {
    width: 15px;
    height: 15px;
    border: 1px solid var(--border-color);
    z-index: 1024;
    border-radius: 3px;
  }
}

.color-group-ul {
  width: 100%;
  padding: 0px 8px;
  margin: 20px 0 8px 0;

  .color-li {
    position: relative;
    width: 100%;
    height: 64px;

    .color-item {
      position: absolute;
      top: 2px;
      left: 0px;
      transform: translateX(-50%) translateY(-50%);
      border-radius: 4px;
      margin: 2px;
      width: 22px;
      height: 22px;
      float: left;
      cursor: pointer;
      box-sizing: border-box;
      background: #409eff;
      border: 1px solid #eeeff1;
    }

    &:last-child {
      height: 16px;
      .line {
        height: 0px;
      }
    }
  }
}

.line {
  pointer-events: none;
  top: 0px;
  bottom: 39px;
  position: absolute;
  width: 3px;
  height: 100%;
  background: #fff;
  left: 0px;
  z-index: 89;
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.5));

  &::before {
    content: "";
    background: #fff;
    display: block;
    width: 9px;
    height: 9px;
    border-radius: 9px;
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
  }
}

.color-item-setting {
  width: 178px;
  height: 36px;
  line-height: 36px;
  background: #f7f9fc;
  float: left;
  text-align: left;
  text-indent: 4px;
  border-radius: 4px;
  color: #2f2e3f;
  font-size: 13px;
  position: absolute;
  white-space: nowrap;
  margin-left: 30px;
  top: -8px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-left: 8px;

  &:hover {
    .btn {
      display: inline-block;
    }
  }

  .btn {
    display: none;
    font-size: 10px;

    & span {
      margin-right: 6px;

      &:hover {
        color: #409eff;
      }
    }
  }
}
</style>
